﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;
using System.Diagnostics;
namespace Socket网络编程
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 点击按钮后开始监听指定端口是否被客户机访问
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_StartMonitor_Click(object sender, EventArgs e)
        {
            try
            { // 当点击开始监听的时候，创建一个负责监听的Socket,地址使用IPV4,流式格式使用TCP协议，数据报格式使用UDP
                Socket monitorSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                // 监听网络上所有接口的客户端活动
                //IPAddress ip = IPAddress.Any;
                // 监听指定接口的客户端活动
                IPAddress ip = IPAddress.Parse(textBox_IP.Text);
                IPEndPoint port = new IPEndPoint(ip, int.Parse(textBox_Port.Text));

                // 绑定到监听Socket
                monitorSocket.Bind(port);

                // 监听成功
                Showlog("监听成功");

                // 设置监听队列
                monitorSocket.Listen(10);

                Thread lisenThread = new Thread(ListenTask);
                lisenThread.IsBackground = true;
                lisenThread.Name = "监听任务";
                lisenThread.Start(monitorSocket);
            }
            catch { MessageBox.Show("异常"); }            
        }

        /// <summary>
        /// 监听所有来自客户端的对指定端口的连接，并为他们各自创建一个用于通信的Socket
        /// </summary>
        /// <param name="arg"></param>
        private void ListenTask(object arg)
        {
            try
            {
                Socket monitorSocket = arg as Socket;
                while (true)
                {
                    // 负责监听的Socket会接收客户端的请求 创建跟客户端通信的Socket
                    Socket socketMsg = monitorSocket.Accept();
                    Showlog(socketMsg.RemoteEndPoint.ToString() + "连接成功");
                    Thread reciveThread = new Thread(ReciveDataTask);
                    reciveThread.IsBackground = true;
                    reciveThread.Name = "接收处理线程";
                    reciveThread.Start(socketMsg);
                }
            }
            catch { MessageBox.Show("异常"); }           
        }


        /// <summary>
        /// 将从客户端接收到的数据写入到textbox中
        /// </summary>
        /// <param name="arg"></param>
        private void ReciveDataTask(object arg)
        {
            try
            {
                Socket socketMsg = arg as Socket;
                while (true)
                {
                    byte[] reciveBuff = new byte[1000];
                    // 如果套接字接收数据缓存没有数据，那么就会一直等待数据到来(默认socketMsg.ReceiveBufferSize大小为8K)
                    // 如果客户机离线，收到的数据便会为0
                    int count = socketMsg.Receive(reciveBuff);
                    if (count == 0)
                    {
                        break;
                    }
                    Showlog(socketMsg.RemoteEndPoint.ToString() + ":" + Encoding.GetEncoding("GB2312").GetString(reciveBuff, 0, count));
                }
            }
            catch { MessageBox.Show("异常"); }           
        }

        /// <summary>
        /// 用于将字符串打印到textbook中的方法
        /// </summary>
        /// <param name="str">需要打印的字符串</param>
        private void Showlog(string str)
        {
            textBox_Log.AppendText(str+"\r\n");
        }

        private int _pictureCount = 0;
        List<Image>imageList = new List<Image>();
        /// <summary>
        /// 用于显示Socket的PPT
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button_Picture_Click(object sender, EventArgs e)
        {
            if (_pictureCount == imageList.Count)
            {
                _pictureCount = 0;
            }
            pictureBox1.Image = imageList[_pictureCount];
            _pictureCount++;
        }

        /// <summary>
        /// 加载Form的时候初始化本地资源
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            // 初始化本地资源
            imageList.Add(Properties.Resources.SocketLearn00);
            imageList.Add(Properties.Resources.SocketLearn01);

            Control.CheckForIllegalCrossThreadCalls = false;

        }
    }
}
